#include "Effect.h"
#include "Character.h"
#include "Monster.h"
#include <random>
#include <iostream>

#pragma region STUN
StunEffect::StunEffect(float prob, int dur)
    : probability(prob), duration(dur) {}

std::string StunEffect::getName() const {
    return "晕眩";
}

float StunEffect::getProbability() const {
    return probability;
}

bool StunEffect::apply(Character& target) const {
    if (checkSuccess()) {
        target.stun = true;
        std::cout << "玩家被" << getName() << "了！" << std::endl;
        return true;
    }
    std::cout << "玩家抵抗住了" << getName() << "效果！" << std::endl;
    return false;
}

bool StunEffect::apply(Monster& target) const {
    if (checkSuccess()) {
        std::cout << target.getName() << "被" << getName() << "了！" << std::endl;
        return true;
    }
    std::cout << target.getName() << "抵抗住了" << getName() << "效果！" << std::endl;
    return false;
}

bool StunEffect::checkSuccess() const {
    static std::mt19937 gen(std::random_device{}());
    std::uniform_real_distribution<> dis(0.0, 1.0);
    return dis(gen) < probability;
}
#pragma endregion

#pragma region ATTACK
AttackBoostEffect::AttackBoostEffect(float prob, int increase)
    : probability(prob), attackIncrease(increase) {}

std::string AttackBoostEffect::getName() const {
    return "攻击力提升";
}

float AttackBoostEffect::getProbability() const {
    return probability;
}

bool AttackBoostEffect::apply(Character& target) const {
    if (checkSuccess()) {
        target.setBaseAttack(attackIncrease);
        std::cout << "玩家攻击力提升了" << attackIncrease << "点！" << std::endl;
        return true;
    }
    std::cout << "玩家尝试提升攻击力，但失败了！" << std::endl;
    return false;
}

bool AttackBoostEffect::apply(Monster& target) const {
    if (checkSuccess()) {
        target.setAttack(target.getAttack() + attackIncrease);
        std::cout << target.getName() << "攻击力提升了" << attackIncrease << "点！" << std::endl;
        return true;
    }
    std::cout << target.getName() << "尝试提升攻击力，但失败了！" << std::endl;
    return false;
}

bool AttackBoostEffect::checkSuccess() const {
    static std::mt19937 gen(std::random_device{}());
    std::uniform_real_distribution<> dis(0.0, 1.0);
    return dis(gen) < probability;
}
#pragma endregion

#pragma region DEFENSE
DefenseBoostEffect::DefenseBoostEffect(float prob, int increase)
    : probability(prob), defenseIncrease(increase) {}

std::string DefenseBoostEffect::getName() const {
    return "防御力提升";
}

float DefenseBoostEffect::getProbability() const {
    return probability;
}

bool DefenseBoostEffect::apply(Character& target) const {
    if (checkSuccess()) {
        target.setBaseDefense(defenseIncrease);
        std::cout << "怪物防御力提升了" << defenseIncrease << "点！" << std::endl;
        return true;
    }
    std::cout << "怪物尝试提升防御力，但失败了！" << std::endl;
    return false;
}

bool DefenseBoostEffect::apply(Monster& target) const {
    if (checkSuccess()) {
        target.setDefense(target.getDefense() + defenseIncrease);
        std::cout << target.getName() << "防御力提升了" << defenseIncrease << "点！" << std::endl;
        return true;
    }
    std::cout << target.getName() << "尝试提升防御力，但失败了！" << std::endl;
    return false;
}

bool DefenseBoostEffect::checkSuccess() const {
    static std::mt19937 gen(std::random_device{}());
    std::uniform_real_distribution<> dis(0.0, 1.0);
    return dis(gen) < probability;
}
#pragma endregion

#pragma region HEALTH
HealEffect::HealEffect(float prob, int amount)
    : probability(prob), healAmount(amount) {}

std::string HealEffect::getName() const {
    return "生命恢复";
}

float HealEffect::getProbability() const {
    return probability;
}

bool HealEffect::apply(Character& target) const {
    if (checkSuccess()) {
        int oldHealth = target.getCurrentHealth();
        int newHealth = std::min(target.getMaxHealth(), oldHealth + healAmount);
        target.setCurrentHealth(newHealth);
        std::cout << "玩家恢复了" << (newHealth - oldHealth) << "点生命值！" << std::endl;
        return true;
    }
    std::cout << "玩家尝试恢复生命，但失败了！" << std::endl;
    return false;
}

bool HealEffect::apply(Monster& target) const {
    if (checkSuccess()) {
        int oldHealth = target.getCurrentHealth();
        int newHealth = std::min(target.getMaxHealth(), oldHealth + healAmount);
        target.setCurrentHealth(newHealth);
        std::cout << target.getName() << "恢复了" << (newHealth - oldHealth) << "点生命值！" << std::endl;
        return true;
    }
    std::cout << target.getName() << "尝试恢复生命，但失败了！" << std::endl;
    return false;
}

bool HealEffect::checkSuccess() const {
    static std::mt19937 gen(std::random_device{}());
    std::uniform_real_distribution<> dis(0.0, 1.0);
    return dis(gen) < probability;
}
#pragma endregion